#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <sys/shm.h>
#include <unistd.h>
#include <stdio.h>
#include <time.h>
#include <sys/wait.h>
#include <string.h>
typedef int sem_t;
int main()
{
    char buf[64];
    key_t key = ftok(getcwd(buf, sizeof(buf)), 'a');
    sem_t semid =  semget(key, 1, IPC_CREAT|0666);
    pid_t pid = fork();
    if(pid == -1)
    {
        perror("fork");
        return -1;
    }
    if(pid > 0)
    {
        
        // 创建共享内存
        key_t shm_key = ftok(buf, 'b');
        int shm_id = shmget(shm_key, 1024, IPC_CREAT | 0644);
        void* msg_buf = shmat(shm_id, 0, 0);
        printf("共享内存创建完成\n");
        memcpy(msg_buf, "hello shm!", strlen("hello shm!")+1);
        printf("sleep(1),让子进程执行\n");
        sleep(1);
        // 使用信号量进行同步
        struct sembuf sem_buf;
        sem_buf.sem_flg = 0;
        sem_buf.sem_op = +1;
        sem_buf.sem_num = 0;
        semop(semid,&sem_buf, 1);
        int status;
        wait(&status);
        shmdt(msg_buf);
        shmctl(shm_id, IPC_RMID,NULL);
        semctl(semid, 0, IPC_RMID);
        printf("程序结束了!\n");
    }
    else if(pid == 0)
    {
        char buf[64];
        key_t key = ftok(getcwd(buf, sizeof(buf)), 'a');
        sem_t semid =  semget(key, 1, 0);
        struct sembuf sem_buf;
        sem_buf.sem_flg = 0;
        sem_buf.sem_op = -1;
        sem_buf.sem_num = 0;
        // V操作
        printf("子进程等待信号量\n");
        semop(semid, &sem_buf, 1);
        // 共享内存
        key_t shm_key = ftok(buf, 'b');
        int shm_id = shmget(shm_key, 0, 0);
        void* msg_buf = shmat(shm_id, 0, 0);
        
        printf("%s\n", (char*)msg_buf);
        sem_buf.sem_op = +1;
        // P操作
        semop(semid, &sem_buf, 1);
        shmdt(msg_buf);
    }
}
